/*        
	Copyright (C) 2010- Peer internet solutions

	Copyright (C) 2013 Pontificia Universidad Catolica del Peru
	contact: http://avatar.inf.pucp.edu.pe/realidad-aumentada/
	address contact: Av. Universitaria 1801, San Miguel, Lima-Peru.

	This file is part of UbicAR PUCP.
	
	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with This program.  If not, see <http://www.gnu.org/licenses/>.
*/
/*
	Modified by: Pedro Carrión Castagnola
	Pontificia Universidad Catolica del Peru
	Direccion de Informatica Academica

	Modified by: Alvaro Roger Agüero Sánchez, Rodolfo Javier Galvez Meza
	Pontificia Universidad Catolica del Peru
	Departamento de Ingeniería
*/

package org.grupoavatar.guiaubicua.mix;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;

import org.grupoavatar.guiaubicua.VAR;
import org.grupoavatar.guiaubicua.VInicial;
import org.grupoavatar.guiaubicua.mix.data.DataSource;
import org.grupoavatar.guiaubicua.mix.data.Servicios;
import org.grupoavatar.guiaubicua.mix.data.DataSource.DATASOURCE;
import org.grupoavatar.guiaubicua.mix.render.Matrix;

import android.app.Dialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.Cursor;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import org.grupoavatar.guiaubicua.R;

public class MixContext extends ContextWrapper {

	public VAR var;
	Context ctx;
	boolean isURLvalid = true;
	Random rand;
	public DownloadManager downloadManager;
	public Location curLoc;
	Location locationAtLastDownload;
	private static final int TWO_MINUTES = 1000 * 60 * 2;
	public Matrix rotationM = new Matrix();
	public float declination = 0f;
	private boolean actualLocation=false;
	LocationManager locationMgr;
	private HashMap<DataSource.DATASOURCE,Boolean> selectedDataSources=new HashMap<DataSource.DATASOURCE,Boolean>();
	private HashMap<Servicios.DATASOURCE,Boolean> selectedServices=new HashMap<Servicios.DATASOURCE,Boolean>();
	public static MixContext mixcontext;
	
	public MixContext(Context appCtx) {
		
		super(appCtx);
		mixcontext = this;
		this.ctx = appCtx.getApplicationContext();

		SharedPreferences settings = getSharedPreferences(VInicial.PREFS_NAME, 0);
		boolean atLeastOneDatasourceSelected = false;
		
		//categorias
		for(DataSource.DATASOURCE source: DataSource.DATASOURCE.values()) {
			// fill the selectedDataSources HashMap with saved settings
			selectedDataSources.put(source, settings.getBoolean(source.toString(), false));
			if(selectedDataSources.get(source))
				atLeastOneDatasourceSelected=true;
		}
		
		//servicios
		for(Servicios.DATASOURCE source: Servicios.DATASOURCE.values()) {
			// fill the selectedDataSources HashMap with saved settings
			selectedServices.put(source, settings.getBoolean(source.toString(), false));
			if(selectedServices.get(source))
				Servicios.atLeastOneServiceSelected=true;
		}
		// if nothing was previously selected  
		if(!atLeastOneDatasourceSelected)	{
//			setDataSource(DATASOURCE.LUGARESURL, true);
//			setDataSource(DATASOURCE.LFACULTADES, true);
//			setDataSource(DATASOURCE.LAUDITORIOS, true);
//			setDataSource(DATASOURCE.LBIBLIOTECAS, true);
//			setDataSource(DATASOURCE.LCAFETERIAS, true);
//			setDataSource(DATASOURCE.LCENTROS, true);
			
			//nuestras categorias genericas
			setDataSource(DATASOURCE.ASESORIA_PASTORAL, true);
			setDataSource(DATASOURCE.ASOCIACIONES_Y_GRUPOS, true);
			setDataSource(DATASOURCE.AUDITORIOS, true);
			setDataSource(DATASOURCE.BANCOS_Y_CAJEROS_AUTOMATICOS, true);
			setDataSource(DATASOURCE.CAFETERIAS, true);
			setDataSource(DATASOURCE.CENTRO_DE_FOTOCOPIADO, true);
			setDataSource(DATASOURCE.CENTROS_DE_ESTUDIOS_Y_CENTROS_DE_INVESTIGACION, true);
			setDataSource(DATASOURCE.COMEDORES_Y_FOOD_COURT, true);
			setDataSource(DATASOURCE.DEPARTAMENTOS_ACADEMICOS, true);
			setDataSource(DATASOURCE.DEPORTES, true);
			setDataSource(DATASOURCE.DIRECCIONES_Y_OFICINAS, true);
			setDataSource(DATASOURCE.EDIFICIOS, true);
			setDataSource(DATASOURCE.EDIFICIOS_MULTIFUNCIONALES, true);
			setDataSource(DATASOURCE.ESTACIONAMIENTOS, true);
			setDataSource(DATASOURCE.FACULTADES, true);
			setDataSource(DATASOURCE.FACULTADES_AUDITORIOS_Y_LABORATORIOS, true);
			setDataSource(DATASOURCE.INSTITUTOS_GENERICO, true);
			setDataSource(DATASOURCE.INSTITUTOS_SUBCATEGORIA, true);
			setDataSource(DATASOURCE.INSTITUTOS_DE_IDIOMAS, true);
			setDataSource(DATASOURCE.LABORATORIOS_Y_TALLERES, true);
			setDataSource(DATASOURCE.LIBRERIAS, true);
			setDataSource(DATASOURCE.MAQUINAS_EXPENDEDORAS, true);
			setDataSource(DATASOURCE.PABELLONES_DE_AULAS, true);
			setDataSource(DATASOURCE.PAGOS_Y_TRANSACCIONES, true);
			setDataSource(DATASOURCE.PAPELERIA_Y_SERVICIOS_DIGITALES, true);
			setDataSource(DATASOURCE.QUIOSCOS, true);
			setDataSource(DATASOURCE.SALAS_DE_LECTURA, true);
			setDataSource(DATASOURCE.SERVICIO_DE_TESORERIA, true);
			setDataSource(DATASOURCE.SERVICIOS_ALIMENTICIOS, true);
			setDataSource(DATASOURCE.SERVICIOS_DE_COMPUTADORAS_E_IMPRESORAS, true);
			setDataSource(DATASOURCE.SERVICIOS_DE_SALUD, true);
			setDataSource(DATASOURCE.SERVICIOS_HIGIENICOS, true);
			setDataSource(DATASOURCE.SISTEMAS_DE_BIBLIOTECAS, true);
			setDataSource(DATASOURCE.SISTEMAS_DE_BIBLIOTECAS_Y_SALAS_DE_LECTURA, true);
			setDataSource(DATASOURCE.TELEFONOS_DE_EMERGENCIA, true);
			setDataSource(DATASOURCE.TELEFONOS_PUBLICOS, true);
			setDataSource(DATASOURCE.TELEFONOS, true);
			setDataSource(DATASOURCE.VARIOS, true);
			//fin nuestras categorias genericas
		}
			

		rotationM.toIdentity();

		int locationHash = 0;
		try {
			locationMgr = (LocationManager) appCtx.getSystemService(Context.LOCATION_SERVICE);
			
			Location lastFix= locationMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
			
			if (lastFix == null){
				lastFix = locationMgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
			}
			if (lastFix != null){
				locationHash = ("HASH_" + lastFix.getLatitude() + "_" + lastFix.getLongitude()).hashCode();

				long actualTime= new Date().getTime();
				long lastFixTime = lastFix.getTime();
				long timeDifference = actualTime-lastFixTime;

				actualLocation = timeDifference <= 1200000;	//20 min --- 300000 milliseconds = 5 min
			}
			else
				actualLocation = false;
			
			
		} catch (Exception ex) {
			ex.printStackTrace();
		}

		rand = new Random(System.currentTimeMillis() + locationHash);
	}
	
	public Location getCurrentGPSInfo() {
		return curLoc != null ? curLoc : locationMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
	}

	public boolean isActualLocation(){
		return actualLocation;
	}

	public DownloadManager getDownloader() {
		return downloadManager;
	}
	
	public void setLocationManager(LocationManager locationMgr){
		this.locationMgr = locationMgr;
	}
	
	public LocationManager getLocationManager(){
		return locationMgr;
	}

	public void getRM(Matrix dest) {
		synchronized (rotationM) {
			dest.set(rotationM);
		}
	}

	public Location getCurrentLocation() {
		if (curLoc != null)	{
			synchronized (curLoc) {
				return curLoc;
			}
		}
		
		return locationAtLastDownload;
	}

	public InputStream getHttpGETInputStream(String urlStr)
	throws Exception {
		InputStream is = null;
		URLConnection conn = null;

		if (urlStr.startsWith("file://"))			
			return new FileInputStream(urlStr.replace("file://", ""));

		if (urlStr.startsWith("content://"))
			return getContentInputStream(urlStr, null);

		if (urlStr.startsWith("https://")) {
			HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){
    			public boolean verify(String hostname, SSLSession session) {
    				return true;
    			}});
		SSLContext context = SSLContext.getInstance("TLS");
		context.init(null, new X509TrustManager[]{new X509TrustManager(){
			public void checkClientTrusted(X509Certificate[] chain,
					String authType) throws CertificateException {}
			public void checkServerTrusted(X509Certificate[] chain,
					String authType) throws CertificateException {}
			public X509Certificate[] getAcceptedIssuers() {
				return new X509Certificate[0];
			}}}, new SecureRandom());
		HttpsURLConnection.setDefaultSSLSocketFactory(
				context.getSocketFactory());
		}
		
		try {
			URL url = new URL(urlStr);
			conn =  url.openConnection();
			conn.setReadTimeout(10000);
			conn.setConnectTimeout(10000);

			is = conn.getInputStream();
			
			return is;
		} catch (Exception ex) {
			try {
				is.close();
			} catch (Exception ignore) {			
			}
			try {
				if(conn instanceof HttpURLConnection)
					((HttpURLConnection)conn).disconnect();
			} catch (Exception ignore) {			
			}
			
			throw ex;				

		}
	}

	public String getHttpInputString(InputStream is) {
		BufferedReader reader = new BufferedReader(new InputStreamReader(is), 8 * 1024);
		StringBuilder sb = new StringBuilder();

		try {
			String line;
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return sb.toString();
	}

	public InputStream getHttpPOSTInputStream(String urlStr,
			String params) throws Exception {
		InputStream is = null;
		OutputStream os = null;
		HttpURLConnection conn = null;

		if (urlStr.startsWith("content://"))
			return getContentInputStream(urlStr, params);

		try {
			URL url = new URL(urlStr);
			conn = (HttpURLConnection) url.openConnection();
			conn.setReadTimeout(10000);
			conn.setConnectTimeout(10000);

			if (params != null) {
				conn.setDoOutput(true);
				os = conn.getOutputStream();
				OutputStreamWriter wr = new OutputStreamWriter(os);
				wr.write(params);
				wr.close();
			}

			is = conn.getInputStream();
			
			return is;
		} catch (Exception ex) {

			try {
				is.close();
			} catch (Exception ignore) {			

			}
			try {
				os.close();
			} catch (Exception ignore) {			

			}
			try {
				conn.disconnect();
			} catch (Exception ignore) {
			}

			if (conn != null && conn.getResponseCode() == 405) {
				return getHttpGETInputStream(urlStr);
			} else {		

				throw ex;
			}
		}
	}

	public InputStream getContentInputStream(String urlStr, String params)
	throws Exception {
		ContentResolver cr = var.getContentResolver();
		Cursor cur = cr.query(Uri.parse(urlStr), null, params, null, null);

		cur.moveToFirst();
		int mode = cur.getInt(cur.getColumnIndex("MODE"));

		if (mode == 1) {
			String result = cur.getString(cur.getColumnIndex("RESULT"));
			cur.deactivate();

			return new ByteArrayInputStream(result
					.getBytes());
		} else {
			cur.deactivate();

			throw new Exception("Invalid content:// mode " + mode);
		}
	}

	public void returnHttpInputStream(InputStream is) throws Exception {
		if (is != null) {
			is.close();
		}
	}

	public void returnResourceInputStream(InputStream is) throws Exception {
		if (is != null)
			is.close();
	}

	public void loadWebPage(String url, Context context) throws Exception {
		WebView webview = new WebView(context);
		
		webview.setWebViewClient(new WebViewClient() {
			public boolean  shouldOverrideUrlLoading  (WebView view, String url) {
			     view.loadUrl(url);
				return true;
			}

		});
				
		Dialog d = new Dialog(context) {
			public boolean onKeyDown(int keyCode, KeyEvent event) {
				if (keyCode == KeyEvent.KEYCODE_BACK)
					this.dismiss();
				return true;
			}
		};
		d.requestWindowFeature(Window.FEATURE_NO_TITLE);
		d.getWindow().setGravity(Gravity.BOTTOM);
		d.addContentView(webview, new FrameLayout.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
				Gravity.BOTTOM));

		d.show();
		
		webview.loadUrl(url);
	}

	public void setDataSource(DataSource.DATASOURCE source, Boolean selection){
		selectedDataSources.put(source,selection);
		SharedPreferences settings = getSharedPreferences(VInicial.PREFS_NAME, 0);
		SharedPreferences.Editor editor = settings.edit();
		editor.putBoolean(source.toString(), selection);
		editor.commit();
	}
	
	public void setService(Servicios.DATASOURCE source, Boolean selection){
		selectedServices.put(source,selection);
		SharedPreferences settings = getSharedPreferences(VInicial.PREFS_NAME, 0);
		SharedPreferences.Editor editor = settings.edit();
		editor.putBoolean(source.toString(), selection);
		editor.commit();
	}
               
	public Boolean isDataSourceSelected(DataSource.DATASOURCE source) {
		return selectedDataSources.get(source);
	}
	
	public Boolean isServiceSelected(Servicios.DATASOURCE source) {
		return selectedServices.get(source);
	}
	
	@SuppressWarnings("incomplete-switch")
	public static String getDataSourceName(DataSource.DATASOURCE source) {
		switch(source) {
			case ASESORIA_PASTORAL:		return VInicial.getContext().getResources().getString(R.string.ASESORIA_PASTORAL);
			case ASOCIACIONES_Y_GRUPOS:		return VInicial.getContext().getResources().getString(R.string.ASOCIACIONES_Y_GRUPOS);
			case AUDITORIOS:	return VInicial.getContext().getResources().getString(R.string.AUDITORIOS);
			case BANCOS_Y_CAJEROS_AUTOMATICOS:	return VInicial.getContext().getResources().getString(R.string.BANCOS_Y_CAJEROS_AUTOMATICOS);
			case CAFETERIAS:	return VInicial.getContext().getResources().getString(R.string.CAFETERIAS);
			case CENTRO_DE_FOTOCOPIADO:	return VInicial.getContext().getResources().getString(R.string.CENTRO_DE_FOTOCOPIADO);
			case CENTROS_DE_ESTUDIOS_Y_CENTROS_DE_INVESTIGACION:	return VInicial.getContext().getResources().getString(R.string.CENTROS_DE_ESTUDIOS_Y_CENTROS_DE_INVESTIGACION);
			case COMEDORES_Y_FOOD_COURT:	return VInicial.getContext().getResources().getString(R.string.COMEDORES_Y_FOOD_COURT);
			case DEPARTAMENTOS_ACADEMICOS: return VInicial.getContext().getResources().getString(R.string.DEPARTAMENTOS_ACADEMICOS);
			case DEPORTES:	return VInicial.getContext().getResources().getString(R.string.DEPORTES);
			case DIRECCIONES_Y_OFICINAS:	return VInicial.getContext().getResources().getString(R.string.DIRECCIONES_Y_OFICINAS);
			case EDIFICIOS_MULTIFUNCIONALES:	return VInicial.getContext().getResources().getString(R.string.EDIFICIOS_MULTIFUNCIONALES);
			case EDIFICIOS:		return VInicial.getContext().getResources().getString(R.string.EDIFICIOS);
			case ESTACIONAMIENTOS:	return VInicial.getContext().getResources().getString(R.string.ESTACIONAMIENTOS);
			case FACULTADES: return VInicial.getContext().getResources().getString(R.string.FACULTADES);
			case FACULTADES_AUDITORIOS_Y_LABORATORIOS:		return VInicial.getContext().getResources().getString(R.string.FACULTADES_AUDITORIOS_Y_LABORATORIOS);
			case INSTITUTOS_SUBCATEGORIA:	return VInicial.getContext().getResources().getString(R.string.INSTITUTOS_SUBCATEGORIA);
			case INSTITUTOS_DE_IDIOMAS:	return VInicial.getContext().getResources().getString(R.string.INSTITUTOS_DE_IDIOMAS);
			case INSTITUTOS_GENERICO:	return VInicial.getContext().getResources().getString(R.string.INSTITUTOS_GENERICO);
			case LABORATORIOS_Y_TALLERES:	return VInicial.getContext().getResources().getString(R.string.LABORATORIOS_Y_TALLERES);
			case LIBRERIAS:		return VInicial.getContext().getResources().getString(R.string.LIBRERIAS);
			case MAQUINAS_EXPENDEDORAS:	return VInicial.getContext().getResources().getString(R.string.MAQUINAS_EXPENDEDORAS);
			case PABELLONES_DE_AULAS:	return VInicial.getContext().getResources().getString(R.string.PABELLONES_DE_AULAS);
			case PAGOS_Y_TRANSACCIONES:		return VInicial.getContext().getResources().getString(R.string.PAGOS_Y_TRANSACCIONES);
			case PAPELERIA_Y_SERVICIOS_DIGITALES:		return VInicial.getContext().getResources().getString(R.string.PAPELERIA_Y_SERVICIOS_DIGITALES);
			case QUIOSCOS:	return VInicial.getContext().getResources().getString(R.string.QUIOSCOS);
			case SALAS_DE_LECTURA:	return VInicial.getContext().getResources().getString(R.string.SALAS_DE_LECTURA);
			case SERVICIO_DE_TESORERIA:	return VInicial.getContext().getResources().getString(R.string.SERVICIO_DE_TESORERIA);
			case SERVICIOS_ALIMENTICIOS:	return VInicial.getContext().getResources().getString(R.string.SERVICIOS_ALIMENTICIOS);
			case SERVICIOS_DE_COMPUTADORAS_E_IMPRESORAS:	return VInicial.getContext().getResources().getString(R.string.SERVICIOS_DE_COMPUTADORAS_E_IMPRESORAS);
			case SERVICIOS_DE_SALUD:		return VInicial.getContext().getResources().getString(R.string.SERVICIOS_DE_SALUD);
			case SERVICIOS_HIGIENICOS:		return VInicial.getContext().getResources().getString(R.string.SERVICIOS_HIGIENICOS);
			case SISTEMAS_DE_BIBLIOTECAS:	return VInicial.getContext().getResources().getString(R.string.SISTEMAS_DE_BIBLIOTECAS);
			case SISTEMAS_DE_BIBLIOTECAS_Y_SALAS_DE_LECTURA:	return VInicial.getContext().getResources().getString(R.string.SISTEMAS_DE_BIBLIOTECAS_Y_SALAS_DE_LECTURA);
			case TELEFONOS:		return VInicial.getContext().getResources().getString(R.string.TELEFONOS);
			case TELEFONOS_DE_EMERGENCIA:	return VInicial.getContext().getResources().getString(R.string.TELEFONOS_DE_EMERGENCIA);
			case TELEFONOS_PUBLICOS:	return VInicial.getContext().getResources().getString(R.string.TELEFONOS_PUBLICOS);
			case VARIOS:		return VInicial.getContext().getResources().getString(R.string.VARIOS);
		}
		return "";
	}
	
	public static String getServiceName(Servicios.DATASOURCE source) {
		Resources tmp = VInicial.getContext().getResources();
		switch(source) {
			case SEPARACION_DE_CANCHAS: return tmp.getString(R.string.SEPARACION_DE_CANCHAS);
			case REALIZACION_DE_EVENTOS: return tmp.getString(R.string.REALIZACION_DE_EVENTOS);
			case ALQUILER_DE_LIBROS: return tmp.getString(R.string.ALQUILER_DE_LIBROS);
			case PRESTAMO_DE_LIBRO: return tmp.getString(R.string.PRESTAMO_DE_LIBRO);
			case SALAS_GRUPALES: return tmp.getString(R.string.SALAS_GRUPALES);
			case IMPRESION: return tmp.getString(R.string.IMPRESION);
			case FOTOCOPIADO: return tmp.getString(R.string.FOTOCOPIADO);
			case CUBICULO: return tmp.getString(R.string.CUBICULO);
			case SALA_DE_LECTURA: return tmp.getString(R.string.SALA_DE_LECTURA);
			case VIDEOTECA: return tmp.getString(R.string.VIDEOTECA);
			case AUDIOTECA: return tmp.getString(R.string.AUDIOTECA);
			case HEMEROTECA: return tmp.getString(R.string.HEMEROTECA);
			case BANOS: return tmp.getString(R.string.BANOS);
			case GIMNASIO: return tmp.getString(R.string.GIMNASIO);
			case ENSENANZA_DE_IDIOMAS: return tmp.getString(R.string.ENSENANZA_DE_IDIOMAS);
			case OFERTA_DE_CURSOS: return tmp.getString(R.string.OFERTA_DE_CURSOS);
			case SERVICIO_DE_COMPUTO: return tmp.getString(R.string.SERVICIO_DE_COMPUTO);
			case VENTA_DE_LIBROS: return tmp.getString(R.string.VENTA_DE_LIBROS);
			case VENTA_DE_MERCHANDAISING: return tmp.getString(R.string.VENTA_DE_MERCHANDAISING);
			case LOGISTICA: return tmp.getString(R.string.LOGISTICA);
			case MUSEO: return tmp.getString(R.string.MUSEO);
			case INFORMES: return tmp.getString(R.string.INFORMES);
			case ATENCION_MEDICA: return tmp.getString(R.string.ATENCION_MEDICA);
			case ATENCION_PSICOPEDAGOGICA: return tmp.getString(R.string.ATENCION_PSICOPEDAGOGICA);
			case PAGOS_Y_COBRANZAS_DE_LA_UNIVERSIDAD: return tmp.getString(R.string.PAGOS_Y_COBRANZAS_DE_LA_UNIVERSIDAD);
			case CUIDADO_DE_BEBES: return tmp.getString(R.string.CUIDADO_DE_BEBES);
			case MISA: return tmp.getString(R.string.MISA);
			case FOTO_DE_CARNET: return tmp.getString(R.string.FOTO_DE_CARNET);
			case CONSULTA_DE_DOCUMENTOS: return tmp.getString(R.string.CONSULTA_DE_DOCUMENTOS);
			case CLASES_DE_BAILE: return tmp.getString(R.string.CLASES_DE_BAILE);
			case CLASES_DE_MUSICA: return tmp.getString(R.string.CLASES_DE_MUSICA);
			case PREPARACION_PRE_UNIVERSITARIA: return tmp.getString(R.string.PREPARACION_PRE_UNIVERSITARIA);
			case PRESTAMOS_DE_AULA: return tmp.getString(R.string.PRESTAMOS_DE_AULA);
			case VENTA_DE_COMIDA: return tmp.getString(R.string.VENTA_DE_COMIDA);
			case MENU: return tmp.getString(R.string.MENU);
			case SOPORTE_TECNICO_INFORMATICO: return tmp.getString(R.string.SOPORTE_TECNICO_INFORMATICO);
			case VENTA_DE_SNACKS: return tmp.getString(R.string.VENTA_DE_SNACKS);
			case SALA_DE_PROFESORES: return tmp.getString(R.string.SALA_DE_PROFESORES);
			case OPERACIONES_BANCARIAS: return tmp.getString(R.string.OPERACIONES_BANCARIAS);
			case AULA_LIBRE: return tmp.getString(R.string.AULA_LIBRE);
			case PRESTAMOS_DE_ESTUDIO_DIGITAL: return tmp.getString(R.string.PRESTAMOS_DE_ESTUDIO_DIGITAL);
		default:
			break;
		}
		return "";
	}
	
	public static int getDataSourceIcon(DataSource.DATASOURCE source) {
		switch(source) {
//			case LFACULTADES:		return R.drawable.icon_fac;
//			case LDEPARTAMENTOS:	return R.drawable.icon_dep;
//			case LUGARESURL:		return R.drawable.icon_gen;
//			case EVENTOSURL:		return R.drawable.icon_eve;
//			case LAUDITORIOS:		return R.drawable.icon_aud;
//			case LBIBLIOTECAS:		return R.drawable.icon_bib;
//			case LCAFETERIAS:		return R.drawable.icon_caf;
////			case LINSTITUTOS:		return R.drawable.icon_cen;
//			case LCENTROS:			return R.drawable.icon_cen;
//			case LDIRECCIONES:		return R.drawable.icon_dir;
//			case LOTROS:			return R.drawable.icon_gen;
			
			//nuevo
			case ASESORIA_PASTORAL:		return R.drawable.cat_1;
			case ASOCIACIONES_Y_GRUPOS:		return R.drawable.cat_2;
			case AUDITORIOS:	return R.drawable.cat_3;
			case BANCOS_Y_CAJEROS_AUTOMATICOS:	return R.drawable.cat_4;
			case CAFETERIAS:	return R.drawable.cat_5;
			case CENTRO_DE_FOTOCOPIADO:	return R.drawable.cat_6;
			case CENTROS_DE_ESTUDIOS_Y_CENTROS_DE_INVESTIGACION:	return R.drawable.cat_7;	
			case COMEDORES_Y_FOOD_COURT:	return R.drawable.cat_8;
			case DEPARTAMENTOS_ACADEMICOS: return R.drawable.cat_9;
			case DEPORTES:	return R.drawable.cat_10;
			case DIRECCIONES_Y_OFICINAS:	return R.drawable.cat_11;
			case EDIFICIOS_MULTIFUNCIONALES:	return R.drawable.cat_12;
			case EDIFICIOS:		return R.drawable.cat_13;
			case ESTACIONAMIENTOS:	return R.drawable.cat_14;
			case FACULTADES: return R.drawable.cat_15;
			case FACULTADES_AUDITORIOS_Y_LABORATORIOS:	return R.drawable.cat_16;		
			case INSTITUTOS_SUBCATEGORIA:	return R.drawable.cat_17;
			case INSTITUTOS_DE_IDIOMAS:	return R.drawable.cat_18;
			case INSTITUTOS_GENERICO:	return R.drawable.cat_19;
			case LABORATORIOS_Y_TALLERES:	return R.drawable.cat_20;
			case LIBRERIAS:		return R.drawable.cat_21;
			case MAQUINAS_EXPENDEDORAS:	return R.drawable.cat_22;
			case PABELLONES_DE_AULAS:	return R.drawable.cat_23;
			case PAGOS_Y_TRANSACCIONES:		return R.drawable.cat_24;
			case PAPELERIA_Y_SERVICIOS_DIGITALES:		return R.drawable.cat_25;
			case QUIOSCOS:	return R.drawable.cat_26;
			case SALAS_DE_LECTURA:	return R.drawable.cat_27;
			case SERVICIO_DE_TESORERIA:	return R.drawable.cat_28;
			case SERVICIOS_ALIMENTICIOS:	return R.drawable.cat_29;
			case SERVICIOS_DE_COMPUTADORAS_E_IMPRESORAS:	return R.drawable.cat_30;
			case SERVICIOS_DE_SALUD:		return R.drawable.cat_31;
			case SERVICIOS_HIGIENICOS:		return R.drawable.cat_32;
			case SISTEMAS_DE_BIBLIOTECAS:	return R.drawable.cat_33;
			case SISTEMAS_DE_BIBLIOTECAS_Y_SALAS_DE_LECTURA:	return R.drawable.cat_34;
			case TELEFONOS:		return R.drawable.cat_35;
			case TELEFONOS_DE_EMERGENCIA:	return R.drawable.cat_36;
			case TELEFONOS_PUBLICOS:	return R.drawable.cat_37;
			case VARIOS:	return R.drawable.cat_38;
			
			default: return R.drawable.cat_38;
			//fin nuevo
		}
		
	}
	
	public static int getServiceIcon(Servicios.DATASOURCE source) {
		switch(source) {
			case SEPARACION_DE_CANCHAS: return R.drawable.serv_1;
			case REALIZACION_DE_EVENTOS: return R.drawable.serv_2;
			case ALQUILER_DE_LIBROS: return R.drawable.serv_3;
			case PRESTAMO_DE_LIBRO: return R.drawable.serv_4;
			case SALAS_GRUPALES: return R.drawable.serv_5;
			case IMPRESION: return R.drawable.serv_6;
			case FOTOCOPIADO: return R.drawable.serv_7;
			case CUBICULO: return R.drawable.serv_8;
			case SALA_DE_LECTURA: return R.drawable.serv_9;
			case VIDEOTECA: return R.drawable.serv_10;
			case AUDIOTECA: return R.drawable.serv_11;
			case HEMEROTECA: return R.drawable.serv_12;
			case BANOS: return R.drawable.serv_13;
			case GIMNASIO: return R.drawable.serv_14;
			case ENSENANZA_DE_IDIOMAS: return R.drawable.serv_15;
			case OFERTA_DE_CURSOS: return R.drawable.serv_16;
			case SERVICIO_DE_COMPUTO: return R.drawable.serv_17;
			case VENTA_DE_LIBROS: return R.drawable.serv_18;
			case VENTA_DE_MERCHANDAISING: return R.drawable.serv_19;
			case LOGISTICA: return R.drawable.serv_20;
			case MUSEO: return R.drawable.serv_21;
			case INFORMES: return R.drawable.serv_22;
			case ATENCION_MEDICA: return R.drawable.serv_23;
			case ATENCION_PSICOPEDAGOGICA: return R.drawable.serv_24;
			case PAGOS_Y_COBRANZAS_DE_LA_UNIVERSIDAD: return R.drawable.serv_25;
			case CUIDADO_DE_BEBES: return R.drawable.serv_26;
			case MISA: return R.drawable.serv_27;
			case FOTO_DE_CARNET: return R.drawable.serv_28;
			case CONSULTA_DE_DOCUMENTOS: return R.drawable.serv_29;
			case CLASES_DE_BAILE: return R.drawable.serv_30;
			case CLASES_DE_MUSICA: return R.drawable.serv_31;
			case PREPARACION_PRE_UNIVERSITARIA: return R.drawable.serv_32;
			case PRESTAMOS_DE_AULA: return R.drawable.serv_33;
			case VENTA_DE_COMIDA: return R.drawable.serv_34;
			case MENU: return R.drawable.serv_35;
			case SOPORTE_TECNICO_INFORMATICO: return R.drawable.serv_36;
			case VENTA_DE_SNACKS: return R.drawable.serv_37;
			case SALA_DE_PROFESORES: return R.drawable.serv_38;
			case OPERACIONES_BANCARIAS: return R.drawable.serv_39;
			case AULA_LIBRE: return R.drawable.serv_40;
			case PRESTAMOS_DE_ESTUDIO_DIGITAL: return R.drawable.serv_41;
			
			default: return -1;
			//fin nuevo
		}
		
	}
	
	@SuppressWarnings("incomplete-switch")
	public int getDataSourceCircleIcon(DataSource.DATASOURCE source) {
		switch(source) {

			case ASESORIA_PASTORAL:		return R.drawable.map_cat_1;
			case ASOCIACIONES_Y_GRUPOS:		return R.drawable.map_cat_2;
			case AUDITORIOS:	return R.drawable.map_cat_3;
			case BANCOS_Y_CAJEROS_AUTOMATICOS:	return R.drawable.map_cat_4;
			case CAFETERIAS:	return R.drawable.map_cat_5;
			case CENTRO_DE_FOTOCOPIADO:	return R.drawable.map_cat_6;
			case CENTROS_DE_ESTUDIOS_Y_CENTROS_DE_INVESTIGACION:	return R.drawable.map_cat_7;	
			case COMEDORES_Y_FOOD_COURT:	return R.drawable.map_cat_8;
			case DEPARTAMENTOS_ACADEMICOS: return R.drawable.map_cat_9;
			case DEPORTES:	return R.drawable.map_cat_10;
			case DIRECCIONES_Y_OFICINAS:	return R.drawable.map_cat_11;
			case EDIFICIOS_MULTIFUNCIONALES:	return R.drawable.map_cat_12;
			case EDIFICIOS:		return R.drawable.map_cat_13;
			case ESTACIONAMIENTOS:	return R.drawable.map_cat_14;
			case FACULTADES: return R.drawable.map_cat_15;
			case FACULTADES_AUDITORIOS_Y_LABORATORIOS:	return R.drawable.map_cat_16;		
			case INSTITUTOS_SUBCATEGORIA:	return R.drawable.map_cat_17;
			case INSTITUTOS_DE_IDIOMAS:	return R.drawable.map_cat_18;
			case INSTITUTOS_GENERICO:	return R.drawable.map_cat_19;
			case LABORATORIOS_Y_TALLERES:	return R.drawable.map_cat_20;
			case LIBRERIAS:		return R.drawable.map_cat_21;
			case MAQUINAS_EXPENDEDORAS:	return R.drawable.map_cat_22;
			case PABELLONES_DE_AULAS:	return R.drawable.map_cat_23;
			case PAGOS_Y_TRANSACCIONES:		return R.drawable.map_cat_24;
			case PAPELERIA_Y_SERVICIOS_DIGITALES:		return R.drawable.map_cat_25;
			case QUIOSCOS:	return R.drawable.map_cat_26;
			case SALAS_DE_LECTURA:	return R.drawable.map_cat_27;
			case SERVICIO_DE_TESORERIA:	return R.drawable.map_cat_28;
			case SERVICIOS_ALIMENTICIOS:	return R.drawable.map_cat_29;
			case SERVICIOS_DE_COMPUTADORAS_E_IMPRESORAS:	return R.drawable.map_cat_30;
			case SERVICIOS_DE_SALUD:		return R.drawable.map_cat_31;
			case SERVICIOS_HIGIENICOS:		return R.drawable.map_cat_32;
			case SISTEMAS_DE_BIBLIOTECAS:	return R.drawable.map_cat_33;
			case SISTEMAS_DE_BIBLIOTECAS_Y_SALAS_DE_LECTURA:	return R.drawable.map_cat_34;
			case TELEFONOS:		return R.drawable.map_cat_35;
			case TELEFONOS_DE_EMERGENCIA:	return R.drawable.map_cat_36;
			case TELEFONOS_PUBLICOS:	return R.drawable.map_cat_37;
			case VARIOS:	return R.drawable.map_cat_38;
		}
		return R.drawable.map_cat_38;
	}
	
	public int getDataSourceCircleIcon(int id) {
		switch(id) {
		case 1:	return R.drawable.map_punto_1;
		//Edif. de Serv. Administrativos		
		case 2:	return R.drawable.map_punto_2;
		//Tinkuy
		case 3:	return R.drawable.map_punto_3;
		//Edificio Dintilhac
		case 4:	return R.drawable.map_punto_4;
		//Edificio Mac Gregor
		case 5:	return R.drawable.map_punto_5;
		//Estudio Digital
		case 6:	return R.drawable.map_punto_6;
		//Gabinetes de Arqueología
		case 7:	return R.drawable.map_punto_7;
		//Laboratorio Biologia
		case 8:	return R.drawable.map_punto_8;
		//Laboratorio Estructuras antisismicas
		case 9:	return R.drawable.map_punto_9;
		//Laboratorio Industrial
		case 10:	return R.drawable.map_punto_10;
		//Laboratorio Mecanica
		case 11:	return R.drawable.map_punto_11;
		//Laboratorio Quimica 
		case 12:	return R.drawable.map_punto_12;
		//Taller Arq
		case 13:	return R.drawable.map_punto_13;
		//Taller Arte
		}
		return 0;
	}
	
	@SuppressWarnings("incomplete-switch")
	public int getDataSourceCircleIconRA(DataSource.DATASOURCE source) {
		switch(source) {
			case ASESORIA_PASTORAL:		return R.drawable.cat_1;
			case ASOCIACIONES_Y_GRUPOS:		return R.drawable.cat_2;
			case AUDITORIOS:	return R.drawable.cat_3;
			case BANCOS_Y_CAJEROS_AUTOMATICOS:	return R.drawable.cat_4;
			case CAFETERIAS:	return R.drawable.cat_5;
			case CENTRO_DE_FOTOCOPIADO:	return R.drawable.cat_6;
			case CENTROS_DE_ESTUDIOS_Y_CENTROS_DE_INVESTIGACION:	return R.drawable.cat_7;	
			case COMEDORES_Y_FOOD_COURT:	return R.drawable.cat_8;
			case DEPARTAMENTOS_ACADEMICOS: return R.drawable.cat_9;
			case DEPORTES:	return R.drawable.cat_10;
			case DIRECCIONES_Y_OFICINAS:	return R.drawable.cat_11;
			case EDIFICIOS_MULTIFUNCIONALES:	return R.drawable.cat_12;
			case EDIFICIOS:		return R.drawable.cat_13;
			case ESTACIONAMIENTOS:	return R.drawable.cat_14;
			case FACULTADES: return R.drawable.cat_15;
			case FACULTADES_AUDITORIOS_Y_LABORATORIOS:	return R.drawable.cat_16;		
			case INSTITUTOS_SUBCATEGORIA:	return R.drawable.cat_17;
			case INSTITUTOS_DE_IDIOMAS:	return R.drawable.cat_18;
			case INSTITUTOS_GENERICO:	return R.drawable.cat_19;
			case LABORATORIOS_Y_TALLERES:	return R.drawable.cat_20;
			case LIBRERIAS:		return R.drawable.cat_21;
			case MAQUINAS_EXPENDEDORAS:	return R.drawable.cat_22;
			case PABELLONES_DE_AULAS:	return R.drawable.cat_23;
			case PAGOS_Y_TRANSACCIONES:		return R.drawable.cat_24;
			case PAPELERIA_Y_SERVICIOS_DIGITALES:		return R.drawable.cat_25;
			case QUIOSCOS:	return R.drawable.cat_26;
			case SALAS_DE_LECTURA:	return R.drawable.cat_27;
			case SERVICIO_DE_TESORERIA:	return R.drawable.cat_28;
			case SERVICIOS_ALIMENTICIOS:	return R.drawable.cat_29;
			case SERVICIOS_DE_COMPUTADORAS_E_IMPRESORAS:	return R.drawable.cat_30;
			case SERVICIOS_DE_SALUD:		return R.drawable.cat_31;
			case SERVICIOS_HIGIENICOS:		return R.drawable.cat_32;
			case SISTEMAS_DE_BIBLIOTECAS:	return R.drawable.cat_33;
			case SISTEMAS_DE_BIBLIOTECAS_Y_SALAS_DE_LECTURA:	return R.drawable.cat_34;
			case TELEFONOS:		return R.drawable.cat_35;
			case TELEFONOS_DE_EMERGENCIA:	return R.drawable.cat_36;
			case TELEFONOS_PUBLICOS:	return R.drawable.cat_37;
			case VARIOS:	return R.drawable.cat_38;
		}
		return R.drawable.cat_38;
	}

	//Sobrecarga para Servicios.DATASOURCE
		public int getDataSourceCircleIconRA(Servicios.DATASOURCE source) {
			switch(source) {
				case SEPARACION_DE_CANCHAS: return R.drawable.serv_1;
				case REALIZACION_DE_EVENTOS: return R.drawable.serv_2;
				case ALQUILER_DE_LIBROS: return R.drawable.serv_3;
				case PRESTAMO_DE_LIBRO: return R.drawable.serv_4;
				case SALAS_GRUPALES: return R.drawable.serv_5;
				case IMPRESION: return R.drawable.serv_6;
				case FOTOCOPIADO: return R.drawable.serv_7;
				case CUBICULO: return R.drawable.serv_8;
				case SALA_DE_LECTURA: return R.drawable.serv_9;
				case VIDEOTECA: return R.drawable.serv_10;
				case AUDIOTECA: return R.drawable.serv_11;
				case HEMEROTECA: return R.drawable.serv_12;
				case BANOS: return R.drawable.serv_13;
				case GIMNASIO: return R.drawable.serv_14;
				case ENSENANZA_DE_IDIOMAS: return R.drawable.serv_15;
				case OFERTA_DE_CURSOS: return R.drawable.serv_16;
				case SERVICIO_DE_COMPUTO: return R.drawable.serv_17;
				case VENTA_DE_LIBROS: return R.drawable.serv_18;
				case VENTA_DE_MERCHANDAISING: return R.drawable.serv_19;
				case LOGISTICA: return R.drawable.serv_20;
				case MUSEO: return R.drawable.serv_21;
				case INFORMES: return R.drawable.serv_22;
				case ATENCION_MEDICA: return R.drawable.serv_23;
				case ATENCION_PSICOPEDAGOGICA: return R.drawable.serv_24;
				case PAGOS_Y_COBRANZAS_DE_LA_UNIVERSIDAD: return R.drawable.serv_25;
				case CUIDADO_DE_BEBES: return R.drawable.serv_26;
				case MISA: return R.drawable.serv_27;
				case FOTO_DE_CARNET: return R.drawable.serv_28;
				case CONSULTA_DE_DOCUMENTOS: return R.drawable.serv_29;
				case CLASES_DE_BAILE: return R.drawable.serv_30;
				case CLASES_DE_MUSICA: return R.drawable.serv_31;
				case PREPARACION_PRE_UNIVERSITARIA: return R.drawable.serv_32;
				case PRESTAMOS_DE_AULA: return R.drawable.serv_33;
				case VENTA_DE_COMIDA: return R.drawable.serv_34;
				case MENU: return R.drawable.serv_35;
				case SOPORTE_TECNICO_INFORMATICO: return R.drawable.serv_36;
				case VENTA_DE_SNACKS: return R.drawable.serv_37;
				case SALA_DE_PROFESORES: return R.drawable.serv_38;
				case OPERACIONES_BANCARIAS: return R.drawable.serv_39;
				case AULA_LIBRE: return R.drawable.serv_40;
				case PRESTAMOS_DE_ESTUDIO_DIGITAL: return R.drawable.serv_41;
				//default:	return R.drawable.cat_38;
			default:
				break;
			}		
			
			return 0;
		}
		
		
	
	public int getDataSourceCircleIconRA(int id) {
		switch(id) {
		case 1:	return R.drawable.punto_1;
		//Edif. de Serv. Administrativos		
		case 2:	return R.drawable.punto_2;
		//Tinkuy
		case 3:	return R.drawable.punto_3;
		//Edificio Dintilhac
		case 4:	return R.drawable.punto_4;
		//Edificio Mac Gregor
		case 5:	return R.drawable.punto_5;
		//Estudio Digital
		case 6:	return R.drawable.punto_6;
		//Gabinetes de Arqueología
		case 7:	return R.drawable.punto_7;
		//Laboratorio Biologia
		case 8:	return R.drawable.punto_8;
		//Laboratorio Estructuras antisismicas
		case 9:	return R.drawable.punto_9;
		//Laboratorio Industrial
		case 10:	return R.drawable.punto_10;
		//Laboratorio Mecanica
		case 11:	return R.drawable.punto_11;
		//Laboratorio Quimica 
		case 12:	return R.drawable.punto_12;
		//Taller Arq
		case 13:	return R.drawable.punto_13;
		//Taller Arte
		}
		return 0;
	}
	
	public void toogleDataSource(DataSource.DATASOURCE source, boolean val) {
		//setDataSource(source, !selectedDataSources.get(source));
		setDataSource(source, val);
	}
	
	public void toogleService(Servicios.DATASOURCE source) {
		setService(source, !selectedServices.get(source));
	}
	
	public void toogleService(Servicios.DATASOURCE source, boolean val) {
		setService(source, val);
	}
	
	public ArrayList<String> getDataSourcesStringList() {
		ArrayList<String> selectedList =  new ArrayList<String>();
		for(DataSource.DATASOURCE source: DataSource.DATASOURCE.values()) {
			if(isDataSourceSelected(source)) {
				selectedList.add(getDataSourceName(source));
			}	
		}
		return selectedList;
	}
	
	/*
	 * Devuelve una lista con las categorías activas que no tienen markers, si todas las activas tienen markers, devuelve null*/
	public String noMarkersCheck() {
		List<Marker> markerList = VInicial.dataView.getDataHandler().getMarkerList();
		if ((markerList == null) || (markerList.isEmpty())) {
			ArrayList<String> selectedEmptyList = getDataSourcesStringList();
			String selectedEmptyListString = "";
			for (int i=0; i<selectedEmptyList.size(); i++)	{
				if (i==0)
					selectedEmptyListString += "\"" + selectedEmptyList.get(i) + "\"";
				else if (i==selectedEmptyList.size()-1)
					selectedEmptyListString += " y \"" + selectedEmptyList.get(i) + "\"";
				else
					selectedEmptyListString += ", \"" + selectedEmptyList.get(i) + "\"";
			}
			if (selectedEmptyList.size()==1)	{
				return "Por el momento la categoría " + selectedEmptyListString + " no tiene contenido. Seleccione otras categorías.";
			}
			else if (selectedEmptyList.size()>1)	{
				return "Por el momento las categorías: " + selectedEmptyListString + " no tienen contenido. Seleccione otras categorías.";
			}
			return null;
		}
		return null;
	}
	
	/*
	 * Return true si no hay markers dentro del radio de visibilidad establecido, false si hay almenos 1 marker dentro de él*/
	public boolean noMarkerInRadius(int radioMetros) {
		List<Marker> markerList = VInicial.dataView.getDataHandler().getMarkerList();
		for (int i=0; i < markerList.size(); i++)	{
			if (markerList.get(i).getDistance() < radioMetros)
				return false;
		}
		return true;
	}

	public Location getLocationAtLastDownload() {
		return locationAtLastDownload;
	}

	public void setLocationAtLastDownload(Location locationAtLastDownload) {
		this.locationAtLastDownload = locationAtLastDownload;
	}
	
	public boolean isBetterLocation(Location location, Location currentBestLocation) {
	    if (currentBestLocation == null) {
	        // A new location is always better than no location
	        return true;
	    }

	    // Check whether the new location fix is newer or older
	    long timeDelta = location.getTime() - currentBestLocation.getTime();
	    boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
	    boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
	    boolean isNewer = timeDelta > 0;

	    // If it's been more than two minutes since the current location, use the new location
	    // because the user has likely moved
	    if (isSignificantlyNewer) {
	        return true;
	    // If the new location is more than two minutes older, it must be worse
	    } else if (isSignificantlyOlder) {
	        return false;
	    }

	    // Check whether the new location fix is more or less accurate
	    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
	    boolean isLessAccurate = accuracyDelta > 0;
	    boolean isMoreAccurate = accuracyDelta < 0;
	    boolean isSignificantlyLessAccurate = accuracyDelta > 200;

	    // Check if the old and new location are from the same provider
	    boolean isFromSameProvider = isSameProvider(location.getProvider(),
	            currentBestLocation.getProvider());

	    // Determine location quality using a combination of timeliness and accuracy
	    if (isMoreAccurate) {
	        return true;
	    } else if (isNewer && !isLessAccurate) {
	        return true;
	    } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
	        return true;
	    }
	    return false;
	}

	/** Checks whether two providers are the same */
	public boolean isSameProvider(String provider1, String provider2) {
	    if (provider1 == null) {
	      return provider2 == null;
	    }
	    return provider1.equals(provider2);
	}
}
